(function (vue) {
  'use strict';

  var script = vue.defineComponent({
    name: "blog-notification",
    props: {
      title: {
        type: String,
        default: '',
      },
      message: {
        type: [String, Object],
        default: '',
      },
      id: {type: String, default: '',},
      duration: {
        type: Number,
        default: 4500,
      },
      offset: {
        type: Number,
        default: 0,
      },
      position: {
        type: String,
        default: 'top',
      },

      onClick: {
        type: Function,
        default: () => void 0,
      },
      onClose: {
        type: Function,
        default: () => void 0,
      },
    },
    emits: ['destroy'],

    setup(props) {

      const visible = vue.ref(false);
      let timer = null;

      function startTimer() {
        if (props.duration > 0) {
          timer = setTimeout(() => {
            if (visible.value) {
              close();
            }
          }, props.duration);
        }
      }

      function clearTimer() {
        clearTimeout(timer);
        timer = null;
      }

      function close() {
        visible.value = false;
      }

      // lifecycle
      vue.onMounted(() => {
        startTimer();
        visible.value = true;
      });

      // styles
      const verticalProperty = vue.computed(() => {
        return props.position.startsWith('top') ? 'top' : 'bottom';
      });

      const positionStyle = vue.computed(() => {
        return {
          [verticalProperty.value]: `${props.offset}px`,
        }
      });

      return {
        visible,
        positionStyle,

        startTimer,
        clearTimer,
        close,
      }
    },

  });

  const _hoisted_1 = { class: "tj-notification__group" };
  const _hoisted_2 = { class: "tj-notification__content" };
  const _hoisted_3 = /*#__PURE__*/vue.createVNode("span", { class: "material-icons" }, "close", -1 /* HOISTED */);

  function render(_ctx, _cache, $props, $setup, $data, $options) {
    return (vue.openBlock(), vue.createBlock(vue.Transition, {
      name: "tj-notification-fade",
      onBeforeLeave: _ctx.onClose,
      onAfterLeave: _cache[5] || (_cache[5] = $event => (_ctx.$emit('destroy')))
    }, {
      default: vue.withCtx(() => [
        vue.withDirectives(vue.createVNode("div", {
          class: "tj-notification",
          style: _ctx.positionStyle,
          id: _ctx.id,
          onMouseenter: _cache[2] || (_cache[2] = (...args) => (_ctx.clearTimer && _ctx.clearTimer(...args))),
          onMouseleave: _cache[3] || (_cache[3] = (...args) => (_ctx.startTimer && _ctx.startTimer(...args))),
          onClick: _cache[4] || (_cache[4] = (...args) => (_ctx.onClick && _ctx.onClick(...args)))
        }, [
          vue.createVNode("div", _hoisted_1, [
            vue.createVNode("h2", {
              class: "tj-notification__title",
              textContent: vue.toDisplayString(_ctx.title)
            }, null, 8 /* PROPS */, ["textContent"]),
            vue.withDirectives(vue.createVNode("div", _hoisted_2, [
              vue.renderSlot(_ctx.$slots, "default", {}, () => [
                vue.createVNode("p", {
                  textContent: vue.toDisplayString(_ctx.message)
                }, null, 8 /* PROPS */, ["textContent"])
              ])
            ], 512 /* NEED_PATCH */), [
              [vue.vShow, _ctx.message]
            ]),
            vue.createVNode("div", {
              class: "tj-notification__closeBtn",
              onClick: _cache[1] || (_cache[1] = vue.withModifiers((...args) => (_ctx.close && _ctx.close(...args)), ["stop"]))
            }, [
              _hoisted_3
            ])
          ])
        ], 44 /* STYLE, PROPS, HYDRATE_EVENTS */, ["id"]), [
          [vue.vShow, _ctx.visible]
        ])
      ]),
      _: 3 /* FORWARDED */
    }, 8 /* PROPS */, ["onBeforeLeave"]))
  }

  script.render = render;
  script.__file = "src/js/notification/index.vue";

  const notifications = {
    'top': [],
    'bottom': [],
  };
  let GAP_SIZE = 16;
  let seed = 1;
  const notify = function (options) {
    const position = options.position || 'top';

    let verticalOffset = options.offset || 0;
    notifications[position].forEach(({vm}) => {
      verticalOffset += (vm.el.offsetHeight || 0) + GAP_SIZE;
    });
    verticalOffset += GAP_SIZE;

    const id = 'notification_' + seed++;
    const userOnClose = options.onClose;
    options = {
      ...options,
      onClose: () => {
        close(id, position, userOnClose);
      },
      offset: verticalOffset,
      id,
    };

    const container = document.createElement('div');
    const vm = vue.createVNode(script, options);

    vm.props.onDestroy = () => {
      vue.render(null, container);
    };

    vue.render(vm, container);
    notifications[position].push({vm});
    document.body.appendChild(container.firstElementChild);
    return {
      close: () => {
        vm.component.proxy.visible = false;
      }
    }
  };

  function close(
    id, position, userOnClose
  ) {
    // maybe we can store the index when inserting the vm to notification list.
    const orientedNotifications = notifications[position];
    const idx = orientedNotifications.findIndex(({ vm }) => vm.component.props.id === id);
    if (idx === -1) return
    const { vm } = orientedNotifications[idx];
    if (!vm) return
    // calling user's on close function before notification gets removed from DOM.
    userOnClose?.(vm);

    // note that this is called @before-leave, that's why we were able to fetch this property.
    const removedHeight = vm.el.offsetHeight;
    const verticalPos = position.split('-')[0];
    orientedNotifications.splice(idx, 1);
    const len = orientedNotifications.length;
    if (len < 1) return
    // starting from the removing item.
    for (let i = idx; i < len; i++) {
      // new position equals the current offsetTop minus removed height plus 16px(the gap size between each item)
      const { el, component } = orientedNotifications[i].vm;
      component.props.offset = parseInt(el.style[verticalPos], 10) - removedHeight - GAP_SIZE;
    }
  }

  const _notify = notify;
  _notify.install = (app) => {
    app.config.globalProperties.$notify = _notify;
  };

  const app = vue.createApp({
    data() {
      return {duration: 1000,};
    },
    methods: {
      showNotify() {
        this.$notify({
          title: '',
          message: '发现新版本点击更新！',
          duration: parseInt(this.duration),
          onClick:()=>{
            window.location.reload();
          },
        });
      }
    },
    mounted() {

    }
  });
  app.use(_notify);
  app.mount('#app');

}(Vue));
